package Bio::Rambam::Proteomics::Formats::Pridexml;
	use namespace::autoclean;
	use Moose;
	use Data::Dumper;
	
	has 'file'					=>	(is=>'rw', isa=>'Str');
	has 'mods_mapping_object'	=>  (is=>'rw',clearer => 'clear_mods_mapping_object');
	
sub read_pridexml{
	my $self=shift;
	my $document=$self->file;

	my $parser = XML::LibXML->new();
	my $doc    = $parser->parse_file($document);

	my %psms;
	my $psms_ref;
	my $spec_number=0;
	my $pep_number=0;
	
	my $peptides_no_correct_seq;
	my $peptides_no_correct_deltamz;
	
	
	#####	Peptides
	foreach my $peptide ($doc->findnodes('/ExperimentCollection/Experiment/GelFreeIdentification/PeptideItem')) {
		$pep_number++; 	last if $pep_number>20;
		my $sequence= $peptide->findvalue('./Sequence');
		my $spectrum_reference=$peptide->findvalue('./SpectrumReference');
		my $peptide_obj= Prideq::peptide->new();
		$peptide_obj->sequence($sequence);
		
		unless ($peptide_obj->validate_correct_aas()){
				# count incorrect sequence aa's
				$peptides_no_correct_seq++;
				next;
		}
		
		foreach my $modification ($peptide->findnodes('./ModificationItem')){
			my $mod_location=$modification->findvalue('./ModLocation');
			my $mod_accession=$modification->findvalue('./ModAccession');
			my $mod_monodelta=$modification->findvalue('./ModMonoDelta');
			my $mod_database=$modification->findvalue('./ModDatabase');
				
			my $modification_obj=Prideq::modification->new();
				$peptide_obj->set_modification({
				    modLocation		=> $mod_location,
				    modAccession	=> $mod_accession,
				    modDatabase		=> $mod_database,
				    modmonodelta	=> $mod_monodelta,
				});		
			}
			
			foreach my $cv_param ($peptide->findnodes('./additional/cvParam')){
				my $cv_label=$cv_param->findvalue('./@cvLabel');
				my $cv_accession=$cv_param->findvalue('./@accession');
				my $cv_name=$cv_param->findvalue('./@name');
				my $cv_value=$cv_param->findvalue('./@value');
				
				my $cv_obj= Prideq::cvparam->new(	'cvLabel'		=> $cv_label,
														'accession'	=> $cv_accession,
														'name'		=> $cv_name,
														'value'		=> $cv_value);
				$peptide_obj->set_cv_param($cv_obj);
			}
			
			$psms{$spectrum_reference}{'peptide'}=$peptide_obj;
			
		}
		
		##### Spectra
		foreach my $spectrum ($doc->findnodes('/ExperimentCollection/Experiment/mzData/spectrumList/spectrum')) {
			my $id=$spectrum->findvalue('./@id');
			next unless defined $psms{$id};
			
			my $spectrum_obj= Prideq::spectrum->new();
			my $spectrum_id=$id;
			my $spectrum_mslevel=$spectrum->findvalue('./spectrumDesc/spectrumSettings/spectrumInstrument/@msLevel');
			
			
			my $precursor_mz=0;
			my $precursor_z=0;
			
			foreach my $cv_precursor_related ($spectrum->findnodes('./spectrumDesc/precursorList/precursor/ionSelection/cvParam')) {
				my $accession=$cv_precursor_related->findvalue('./@accession');
				my $value=$cv_precursor_related->findvalue('./@value');
				$precursor_mz=$value if (($accession eq 'PSI:1000040')	or	($accession eq 'MS:1000744'));
				$precursor_z=$value if 	(($accession eq 'PSI:1000041')	or	($accession eq 'MS:1000041'));
			}
			
			my $array_int=$spectrum->findvalue('./intenArrayBinary/data');
			my $array_int_precision=$spectrum->findvalue('./intenArrayBinary/data/@precision');
			my $array_int_endianess=$spectrum->findvalue('./intenArrayBinary/data/@endian');
			my $array_mz=$spectrum->findvalue('./mzArrayBinary/data');
			my $array_mz_precision=$spectrum->findvalue('./mzArrayBinary/data/@precision');
			my $array_mz_endianess=$spectrum->findvalue('./mzArrayBinary/data/@endian');
			
			$spectrum_obj	->	spectrum_msLevel					($spectrum_mslevel);
			$spectrum_obj	->	spectrum_identifier					($spectrum_id);
			$spectrum_obj	->	precursor_mz						($precursor_mz);
			$spectrum_obj	->	precursor_z							($precursor_z);
			$spectrum_obj	->	spectrum_mzArrayBinary_array		($array_mz);
			$spectrum_obj	->	spectrum_mzArrayBinary_precission	($array_mz_precision);
			$spectrum_obj	->	spectrum_mzArrayBinary_endian		($array_mz_endianess);
			$spectrum_obj	->	spectrum_intenArrayBinary_array		($array_int);
			$spectrum_obj	->	spectrum_intenArrayBinary_precission($array_int_precision);
			$spectrum_obj	->	spectrum_intenArrayBinary_endian	($array_int_endianess);	
			
			$spectrum_obj	->	translate_spectra();
			$spectrum_obj	->	clear_binary_data();
			$psms{$id}{'spectrum'}=$spectrum_obj;
			$spec_number++;  last if $spec_number>10000000;
		}
		
		
		###### psm's treatment
		foreach my $id(sort {$a<=>$b} keys %psms){
			my $spectrum_obj=$psms{$id}{'spectrum'};
			my $peptide_obj=$psms{$id}{'peptide'};
			next unless $spectrum_obj;
			next unless $peptide_obj;
			
			$self->mods_mapping_object->map_peptide_to_main($peptide_obj);
			
			my $psm=Prideq::psm->new(peptide=>$peptide_obj,spectrum=>$spectrum_obj,index=>$id);			
			$psm->validate_delta_mz();

			if ($psm->correct_delta_mz){
				my ($peptide_score,$level)=$psm->theoretical_frags_peptide_score({
					serie_types	=>	['b','y'],
					precission	=>	0.5,
				});
				my $peptide_score_value=Prideq::score->new(name=>'PRIDEQ_PEPTIDE_SCORE',value=>$peptide_score);
				$psm->set_score($peptide_score_value);
				my $peptide_score_level=Prideq::score->new(name=>'PRIDEQ_PEPTIDE_SCORE_LEVEL',value=>$level);
				$psm->set_score($peptide_score_level);
			}
			else{
				### count incorrect delta_mz
				$peptides_no_correct_deltamz++;
				next;
			}
			
			
			
			my @cvs_peptide=$psm->peptide->get_cv_params();
			foreach my $cv(@cvs_peptide){
				if ($cv->accession eq 'PRIDE:0000069'){
					my $score=Prideq::score->new(name=>'MASCOT_SCORE',value=>$cv->value);
					$psm->set_score($score);
				}
				elsif ($cv->accession eq 'PRIDE:0000176'){
					my $score=Prideq::score->new(name=>'XTANDEM_HYPER_SCORE',value=>$cv->value);
					$psm->set_score($score);
				}
				elsif ($cv->accession eq 'PRIDE:0000183'){
					my $score=Prideq::score->new(name=>'XTANDEM_EXPECTANCY_SCORE',value=>$cv->value);
					$psm->set_score($score);
				}
				elsif ($cv->accession eq 'PRIDE:0000053'){
					my $score=Prideq::score->new(name=>'SEQUEST_SCORE',value=>$cv->value);
					$psm->set_score($score);
				}
				elsif ($cv->accession eq 'PRIDE:0000013'){
					my $score=Prideq::score->new(name=>'X_CORRELATION',value=>$cv->value);
					$psm->set_score($score);
				}
				elsif ($cv->accession eq 'PRIDE:0000012'){
					my $score=Prideq::score->new(name=>'DELTA_CN',value=>$cv->value);
					$psm->set_score($score);
				}
				elsif ($cv->accession eq 'PRIDE:0000177'){
					my $score=Prideq::score->new(name=>'SPECTRUM_MILL_PEPTIDE_SCORE',value=>$cv->value);
					$psm->set_score($score);
				}
				elsif ($cv->accession eq 'PRIDE:0000185'){
					my $score=Prideq::score->new(name=>'OMSSA_E_VALUE',value=>$cv->value);
					$psm->set_score($score);
				}
				elsif ($cv->accession eq 'PRIDE:0000186'){
					my $score=Prideq::score->new(name=>'OMSSA_P_VALUE',value=>$cv->value);
					$psm->set_score($score);
				}
				
			}
			$psm->peptide -> clear_cv_params();
			$psm->peptide -> clear_fragment_series();
			$psm->spectrum-> clear_spectrum_data();
			push @{$psms_ref},$psm;
		}
		return $psms_ref;
	}



__PACKAGE__->meta->make_immutable;